//! 交易模块 - 定义交易数据结构及签名验证逻辑

use ring::signature::Ed25519KeyPair; // 移除 , KeyPair};
use serde::{Serialize, Deserialize};
use hex;
use sha2::{Sha256, Digest};

/*
// src/transaction.rs
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TransactionType {
    Legacy,     // 旧版本交易
    Normal,     // 普通转账
    BbsPost,    // BBS帖子
    BbsComment  // BBS评论
}
*/

/// 区块链交易结构
//#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
//#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
//pub struct Transaction {
//    pub tx_type: TransactionType,  // 新增类型字段
//    /// 发送方地址（公钥的十六进制字符串）
//    pub sender: String,
//    /// 接收方地址（公钥的十六进制字符串）
//    pub receiver: String,
//    /// 转账金额（无小数设计，单位：最小代币单位）
//    pub amount: u64,
//    /// 交易签名（发送方私钥对交易内容的签名）
//    pub signature: Vec<u8>,
//    pub hash: String,  // 新增哈希字段
//}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
//#[serde(tag = "tx_type", content = "data")] // 新增serde属性
#[serde(untagged)] // 关键修改：使用非标签联合解析
pub enum Transaction {
    #[serde(rename = "legacy")]
    Legacy {
        sender: String,
        receiver: String,
        amount: u64,
        signature: Vec<u8>,
        //#[serde(default)] // 允许旧数据缺失该字段
	#[serde(default, skip_serializing_if = "String::is_empty")] // ▲▲▲ 新增序列化条件
        hash: String,
    },
    #[serde(rename = "bbs_post")]
    BbsPost {
        author: String,
        content_hash: String,
        proof: String,
        signature: Vec<u8>,
        hash: String,
    },
    #[serde(rename = "bbs_comment")]
    BbsComment {
        post_hash: String,
        author: String,
        content_hash: String,
	proof: String, // 新增字段存储url
        signature: Vec<u8>,
        hash: String,
    },
}

impl Transaction {
    /// 创建新交易（未签名状态）
    /// # 参数
    /// - sender: 发送方钱包地址  
    /// - receiver: 接收方钱包地址  
    /// - amount: 转账金额
    pub fn new(sender: String, receiver: String, amount: u64) -> Self {
/*        Transaction {
            sender,
            receiver,
            amount,
            signature: Vec::new(), // 初始无签名
        }
*/
/*        let mut tx = Self {
            tx_type: TransactionType::Normal,
            sender,
            receiver,
            amount,
            signature: Vec::new(),
            hash: String::new(),
        };
*/
        let mut tx = Self::Legacy {
            sender,
            receiver,
            amount,
            signature: Vec::new(),
            hash: String::new(),
        };
        tx.calculate_hash();
        tx
    }

    pub fn calculate_hash(&mut self) {
/*        let mut hasher = Sha256::new();
        hasher.update(format!(
            "{}{}{}{}",
            self.tx_type.as_str(),  // 需要添加这个方法
            self.sender,
            self.receiver,
            self.amount
        ));
        self.hash = hex::encode(hasher.finalize());
*/
        // 修改哈希计算方法
        let hash_str = match self {
            Self::Legacy { sender, receiver, amount, .. } => {
                format!("legacy|{sender}|{receiver}|{amount}")
            }
            Self::BbsPost { author, content_hash, .. } => {
                format!("post|{author}|{content_hash}")
            }
            Self::BbsComment { post_hash, content_hash, .. } => {
                format!("comment|{post_hash}|{content_hash}")
            }
        };
        
        let mut hasher = Sha256::new();
        hasher.update(hash_str);
        let new_hash = hex::encode(hasher.finalize());
        
        match self {
            Self::Legacy { hash, .. } => *hash = new_hash,
            Self::BbsPost { hash, .. } => *hash = new_hash,
            Self::BbsComment { hash, .. } => *hash = new_hash,
        }
    }

    /// 使用钱包密钥对进行交易签名
    /// # 参数
    /// - key_pair: 发送方的Ed25519密钥对  
    /// # 注意
    /// 签名内容为交易消息的二进制数据，签名后存储到signature字段
    pub fn sign(&mut self, key_pair: &Ed25519KeyPair) {
        // 获取交易消息的二进制数据
        let message = self.get_message();
        // 使用私钥生成签名
//        self.signature = key_pair.sign(message.as_ref())
//            .as_ref()
//            .to_vec();
	
        let signature = key_pair.sign(&message).as_ref().to_vec();
        
        match self {
            Self::Legacy { signature: s, .. } => *s = signature,
            Self::BbsPost { signature: s, .. } => *s = signature,
            Self::BbsComment { signature: s, .. } => *s = signature,
        }
    }

    /// 验证交易签名有效性
    /// # 返回
    /// bool: true表示签名有效，false表示无效或被篡改
/*    pub fn verify(&self) -> bool {
        // 解码发送方公钥（十六进制字符串转字节）
        let public_key_bytes = match hex::decode(&self.sender) {
            Ok(bytes) => bytes,
            Err(_) => return false, // 地址格式错误直接返回无效
        };
        
        // 创建未解析的公钥对象（使用ED25519算法）
        let public_key = ring::signature::UnparsedPublicKey::new(
            &ring::signature::ED25519, 
            &public_key_bytes
        );
        
        // 验证签名：公钥、原始消息、签名三者是否匹配
        public_key.verify(
            self.get_message().as_ref(), 
            self.signature.as_slice()
        ).is_ok() // 转换Result为bool
    }
*/
    pub fn verify(&self) -> bool {
        match self {
            // 只验证 Legacy 交易类型
            Self::Legacy { sender, signature, .. } => {
                let public_key_bytes = match hex::decode(sender) {
                    Ok(bytes) => bytes,
                    Err(_) => return false,
                };
                
                let public_key = ring::signature::UnparsedPublicKey::new(
                    &ring::signature::ED25519,
                    &public_key_bytes
                );
                
                public_key.verify(
                    self.get_message().as_ref(),
                    signature.as_slice()
                ).is_ok()
            }
            // BBS 交易暂不验证
	    // BBS交易跳过签名验证
            Transaction::BbsPost { .. } | Transaction::BbsComment { .. } => true
        }
    }

    /// 生成交易签名消息（防篡改数据）
    /// 消息格式：发送方地址 + 接收方地址 + 金额（字符串拼接）
    /// 例如："addr1addr2100"
    pub fn get_message(&self) -> Vec<u8> {
/*        format!(
            "{}{}{}", 
            self.sender, 
            self.receiver, 
            self.amount
        ).into_bytes()
*/
        match self {
            Self::Legacy { sender, receiver, amount, .. } => 
                format!("{}{}{}", sender, receiver, amount).into_bytes(),
            Self::BbsPost { author, content_hash, .. } =>
                format!("{}{}", author, content_hash).into_bytes(),
            Self::BbsComment { post_hash, content_hash, .. } =>
                format!("{}{}", post_hash, content_hash).into_bytes(),
        }
    }
/*
    pub fn to_storage_value(&self) -> serde_json::Value {
        match self {
            Self::Legacy { sender, receiver, amount, signature, .. } => {
                // 保持旧格式不添加tx_type
                json!({
                    "sender": sender,
                    "receiver": receiver,
                    "amount": amount,
                    "signature": signature
                })
            }
            _ => serde_json::to_value(self).unwrap()
        }
    } 
*/
}

/*
// 为TransactionType添加辅助方法
impl TransactionType {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Legacy => "Legacy",
            Self::Normal => "Normal",
            Self::BbsPost => "BbsPost",
            Self::BbsComment => "BbsComment",
        }
    }
}
*/
